Android窗口管理分析(一)——View是如何绘制到屏幕上的

Android窗口管理分析(一)——View是如何绘制到屏幕上的

窗口管理涉及到的模块很多,除了WindowManagerService还包括SurfaceFlinger服务、Linux的共享内存及tmpfs文件系统、Binder通信、InputManagerService、VSYNC同步技术等。

View的窗口管理分为哪些部分?

窗口管理

WMS是负责View绘制的吗?

WMS的作用是窗口管理,不负责View的绘制,真正完成图像绘制的是SurfaceFlinger服务

WMS(WindowManagerService)是负责Android的窗口的管理,比如窗口的添加、移除、调整顺序等等。至于图像的绘制和合成都不是WMS管理的范畴。

1
2
3
4
5
6
7
8
9
TextView mview=new TextView(context);
...<!--设置颜色 样式-->
WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
wmParams.format = PixelFormat.RGBA_8888;
wmParams.width = 800;
wmParams.height = 800;
mWindowManager.addView(mview, wmParams);
  1. 在利用WindowManager.addView添加窗口之前,TextView的onDraw不会被调用,也就是说View必须被添加到窗口中,才会被绘制。换句话说,只有申请了依附窗口,View才会有可以绘制的目标内存。
  2. 在添加窗口的时候,除了WMS自己进行注册整理,还需要向SurfaceFlinger服务申请一块Surface画布,对应的是一块内存。
  3. 只有这块内存申请成功之后,APP才会有绘画的目标,这块内存是APP和SurfaceFlinger服务端共享的,省去了绘图资源的拷贝。

Android绘图原理

可以看到App通过unLockCanvasAndPost直接和SurfaceFlinger通信进行重绘的。WMS只负责窗口的管理,不负责绘制。

窗口分组是什么样的?

Android中的窗口主要分为三种:

  1. 系统窗口——Toast
  2. 应用窗口——Dialog、Activity。不过Dialog必须依附Activity才能存在
  3. 子窗口——PopupWindow,必须依附其他窗口,依附的窗口只能是1,2而不能是3

窗口组织形式

WMS不仅只是管理窗口,还负责窗口动画,Touch事件等等。

View绘制的内存分配是什么机制?

每个Activity看做一个图层,对应一块Surface,Surface绘图表面对应的内存是SurfaceFlinger申请的,内存是APP与SurfaceFlinger间进程共享的,所以APP和SurfaceFlinger的通信基于共享内存实现的。

共享内存的具体实现是什么样的?

共享内存是基于MAP+tmpfs文件系统实现,可以理解为SF为APP申请一块内存,然后通过binder将内存相关的信息传递给APP,APP端在这块内存中绘制内容,绘制完毕后通知SF图层混排,再由SF将数据渲染到屏幕上,这么做的目的主要考虑图像内存比较大,用socket,binder方式传递效率上无法满足要求。

共享内存具体实现

  1. SurfaceFlinger服务属于系统服务,主要用于将APP绘制完毕的数据渲染到屏幕上。
  2. 各应用的View的绘制都需要经过SurfaceFlinger服务。
  3. WindowManagerService:WMS控制Surface画布的添加和次序,动画还有触摸事件。
  4. 每个App进程负责相应图层的绘制。
  5. App与SurfaceFlinger通信是通过匿名内存来实现的。